package com.wish233.loadbalance.impl.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.wish233.loadbalance.LoadBalancer;
import com.wish233.model.register.ServiceMetaInfo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 一致性哈希负载均衡器
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @learn <a href="https://codefather.cn">鱼皮的编程宝典</a>
 * @from <a href="https://yupi.icu">编程导航学习圈</a>
 */
public class ConsistentHashLoadBalancer implements LoadBalancer {

    public static final int VIRTUAL_NODE_NUM = 100;
    private final TreeMap<Integer, ServiceMetaInfo> virtualNodes = new TreeMap<>();

    @Override
    public ServiceMetaInfo select(List<ServiceMetaInfo> infoList, Map<String, Object> requestParams) {
        int size = infoList.size();
        if (CollectionUtil.isEmpty(infoList)) {
            return null;
        }
        //构建虚拟节点
        for (ServiceMetaInfo info : infoList) {
            for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
                int hash = getHash(info.getServiceAddress() + "#" + i);
                virtualNodes.put(hash, info);
            }
        }
        int hash = getHash(requestParams);
        Map.Entry<Integer, ServiceMetaInfo> ceilingEntry = virtualNodes.ceilingEntry(hash);
        if (ceilingEntry == null) {
            return virtualNodes.firstEntry().getValue();
        }
        return ceilingEntry.getValue();
    }

    private int getHash(Object key) {
        return key.hashCode();
    }
}
